/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Facade;

import DAO.exceptions.NonexistentEntityException;
import Entidad.Cargo;
import Entidad.Proyecto;
import Entidad.Rol;
import Entidad.Usuario;
import Exceptions.CantRemoveActivity;
import Exceptions.CantRemoveFlow;
import Facade.Helpers.CloseEntityManager;
import Facade.Helpers.RandomString;
import Service.ServiceFactory;
import Facade.Helpers.ServiceMail;
import VO.*;
import VO.VW.TareaVW;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeMap;
import javassist.NotFoundException;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.EntityTransaction;
import javax.persistence.Persistence;
import javax.transaction.UserTransaction;

/**
 *
 * @author David
 */
public class Facade{
    
    public UsuarioVO Login(String username) throws NonexistentEntityException{
        EntityManagerFactory emf = null;
        EntityManager em = null;
        UsuarioVO userVO = new UsuarioVO();
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            userVO = ServiceFactory.createUserServices().readUser(username, em);
            if(userVO == null)
               throw new NonexistentEntityException("No existe la persona" + username);
        }
        finally {
            CloseEntityManager.close(em);
        } 
        return userVO;
    }
    
    public ProyectoVO showProject(int id) throws NonexistentEntityException{
        
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        ProyectoVO projectVO = new ProyectoVO();
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            projectVO = ServiceFactory.createProjectServices().readProject(id, em);
        }
        finally {
            CloseEntityManager.close(em);
        }
        return projectVO;
    }
    
    public FlujoVO showFlow(int id) throws NonexistentEntityException{
        
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        FlujoVO flujoVO = new FlujoVO();
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            flujoVO = ServiceFactory.createFlowServices().readFlow(id, em);
        }
        finally {
            CloseEntityManager.close(em);
        }
        return flujoVO;
    }
    
     public ActividadVO showActivity(int id) throws NonexistentEntityException{
        
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        ActividadVO actividadVO = new ActividadVO();
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            actividadVO = ServiceFactory.createActivityServices().readActivity(id, em);
        }
        finally {
            CloseEntityManager.close(em);
        }
        return actividadVO;
    }
    
    public TareaVO showTask(int id) throws NonexistentEntityException{
        
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        TareaVO tareaVO = new TareaVO();
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            tareaVO = ServiceFactory.createTaskServices().readTask(id, em);
        }
        finally {
            CloseEntityManager.close(em);
        }
        return tareaVO;
    } 
    
    
    
    public void removeFlow(int id) throws CantRemoveFlow {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            tx = em.getTransaction(); 
            FlujoVO vo = ServiceFactory.createFlowServices().readFlow(id, em);
            if(vo != null && !vo.getActividadCollection().isEmpty())
                throw new CantRemoveFlow();
            tx.begin();
            ServiceFactory.createFlowServices().deleteFlow(id, em);
            tx.commit();
        }
        finally {
            CloseEntityManager.close(em);
        }
    }
    
    
    public void removeActivity(int id) throws CantRemoveActivity {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            tx = em.getTransaction(); 
            ActividadVO vo = ServiceFactory.createActivityServices().readActivity(id, em);
            if(vo != null && vo.getTareaCollection().size()!=0)
                throw new CantRemoveActivity();
            tx.begin();
            ServiceFactory.createActivityServices().deleteActivity(id, em);
            tx.commit();
        }
        finally {
            CloseEntityManager.close(em);
        }
    }
     
    public void removeTask(int id) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            tx = em.getTransaction(); 
            tx.begin();
            ServiceFactory.createTaskServices().dropTask(id, em);
            tx.commit();
        }
        finally {
            CloseEntityManager.close(em);
        }
    }
    
    public CodigoVO validateCode(String codigo) throws NonexistentEntityException {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        CodigoVO codigoVO = new CodigoVO();
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            codigoVO = ServiceFactory.createCodeServices().readCode(codigo, em);
        }
        finally {
            CloseEntityManager.close(em);
        }
        return codigoVO;
    }
    
    public boolean createManager(UsuarioVO vo) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        boolean state = true;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createUserServices().createUser(vo,em);
           tx.commit();           
        }
        catch(Exception e) {
            if(em!=null && tx!=null) {
                state = false;
                tx.rollback();
            }
        }
        finally {
            CloseEntityManager.close(em);
            return state;
        }
    }

    public void createProject(ProyectoVO proyectoVo, UsuarioVO usuarioVo) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createProjectServices().createProject(proyectoVo,usuarioVo,em);
           tx.commit();  
        }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
    }
    
     public void createFlow(FlujoVO flujoVo) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createFlowServices().createFlow(flujoVo, em);
           tx.commit();  
        }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
     }
     
     public void createActivity(ActividadVO actividadVo) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createActivityServices().createActivity(actividadVo, em);
           tx.commit();  
        }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
                e.printStackTrace();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
     }
     
     
     public void createTask(TareaVO tareaVo) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createTaskServices().createTask(tareaVo, em);
           tx.commit();  
        }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
                e.printStackTrace();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
     }
     
     
     public List<UsuarioVO> showCollaborators(){
         List<UsuarioVO> listaVos = null;
         EntityManagerFactory emf = null;
        EntityManager em = null;
        EntityTransaction tx = null;
        try {
            emf = Persistence.createEntityManagerFactory("manuPU");
            em = emf.createEntityManager();
            tx = em.getTransaction();
            tx.begin();
            listaVos = ServiceFactory.createUserServices().getAllUsers(em);
            System.out.println("Facade " + listaVos.get(0).getNombre());
            tx.commit();
        }catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
        return listaVos;
     }
     
     public void updateResponsabilities(Cargo cargo) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createRespServices().updateResponsability(cargo, em);
           tx.commit();  
        }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
                e.printStackTrace();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
     }
     
     
     public List<String> getResponsabilities(String username){
         EntityManagerFactory emf = null;
         EntityManager em = null;
         EntityTransaction tx = null;
         List<String> listaCargos = new ArrayList<String>();
         try{
             emf = Persistence.createEntityManagerFactory("manuPU");
             em = emf.createEntityManager();
             tx = em.getTransaction();
             tx.begin();
             UsuarioVO user = ServiceFactory.createUserServices().readUser(username, em);
             for(Cargo cargo:user.getCargoCollection()){
                 listaCargos.add(cargo.getNombre());
             }
             tx.commit();
         }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
            }
        }
         finally {
            CloseEntityManager.close(em);
            return listaCargos;
        }
     }

     /**
      * Clase encargada de gestionar los servicios relacionados con el envío de invitaciones
      * recibe el correo al cual envía y el del gerente para vincularlo a la base de datos.
      * @param correo
      * @param correoGerente
      * @return 
      */
     public String inviteCollaborators(String[] correos, String correoGerente){
         /*EntityManagerFactory emf = null;
         EntityManager em = null;
         EntityTransaction tx = null;
         try{
             emf = Persistence.createEntityManagerFactory("manuPU");
             em = emf.createEntityManager();
             tx = em.getTransaction();
             tx.begin();
             UsuarioVO userGerente = ServiceFactory.createUserServices().readUser(correoGerente, em);
             ProyectoVO proyecto = ServiceFactory.createProjectServices().readProject(userGerente.getIdproyecto().getIdproyecto(), em);
//             if (proyecto.getPersonaCollection() == null){
//                 List<Usuario> lista = new ArrayList<Usuario>();
//                 proyecto.setPersonaCollection(lista);
//                 ServiceFactory.createProjectServices().updateProject(proyecto, em);
//             }                 
             //RolVO rol = ServiceFactory.createRolServices().readRol(new Integer(3), em);
             TreeMap mailTree = new TreeMap();
             for(String correo:correos){
                UsuarioVO collaborator = new UsuarioVO();
                collaborator.setCorreo(correo);
                collaborator.setNombre("Pendiente");
                collaborator.setApellido("Pendiente");
                collaborator.setIdproyecto(userGerente.getIdproyecto());
                RandomString random = new RandomString(6);
                String clave =  random.nextString();
                collaborator.setClave(clave);
                collaborator.setIdrol(rol.toEntity());
                ServiceFactory.createUserServices().createUser(collaborator, em);
                mailTree.put(correo, clave);
             }
             //List<Usuario> listaUsuarios = (List<Usuario>) proyecto.getPersonaCollection();
             //listaUsuarios.add(collaborator.toEntity());
             //proyecto.setPersonaCollection(listaUsuarios);
             //ServiceFactory.createProjectServices().updateProject(proyecto, em);
             //ArrayList<String> listaCorreos = new ArrayList<String>();
             //listaCorreos.add(correo);
             ServiceMail.sendInvitation(mailTree, userGerente.getNombre());
             tx.commit();
             
         }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
            }
            e.printStackTrace();
            return "Algo ha fallado";
        }
         finally {
            CloseEntityManager.close(em);
            * 
            */
            return "Colaborador invitado exitosamente";
     }
     
     public List<TareaVW> getTareasByIdUser(String correo){
         EntityManagerFactory emf = null;
         EntityManager em = null;
         EntityTransaction tx = null;
         List<TareaVW> listaVista = new ArrayList<TareaVW>();
         try{
             emf = Persistence.createEntityManagerFactory("manuPU");
             em = emf.createEntityManager();
             tx = em.getTransaction();
             tx.begin();
             List<TareaVO> listaTareas = ServiceFactory.createTaskServices().getTasksByIDProyect(App.Sesion.getIdproyecto(), em);
             if (listaTareas != null){
                for (TareaVO tarea:listaTareas){
                    TareaVW tareaVista = new TareaVW();
                    tareaVista.setIdActividad(tarea.getIdactividad().getIdactividad());
                    tareaVista.setIdTarea(tarea.getIdtarea());
                    List<String> listaUsuarios = new ArrayList<String>();
                    for (UsuarioVO usuario:tarea.getPersonaCollection()){
                        listaUsuarios.add(usuario.getNombre()+" "+usuario.getApellido());
                    }
                    tareaVista.setListaUsuarios(listaUsuarios);
                    tareaVista.setPorcentaje(tarea.getPorcentaje());
                    listaVista.add(tareaVista);
                }
             }else
                 throw new Exception();
             tx.commit();
             
         }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
            }
            e.printStackTrace();
        }
         finally {
            CloseEntityManager.close(em);
            return listaVista;
        }
        
     }
     
//     public String sendMessage(String mailSender, String mailReceiver, String message){
//         EntityManagerFactory emf = null;
//         EntityManager em = null;
//         EntityTransaction tx = null;
//         try{
//             emf = Persistence.createEntityManagerFactory("manuPU");
//             em = emf.createEntityManager();
//             tx = em.getTransaction();
//             tx.begin();
//             
//     }

    public void updateTarea(TareaVO t) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createTaskServices().updateTask(t, em);
           tx.commit();  
        }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
                e.printStackTrace();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
    }

    public void assignTask(TareaVO tareaVo, UsuarioVO usuarioVo) {
        EntityManagerFactory emf = null;
        EntityManager em = null; 
        EntityTransaction tx = null;
        try {
           emf = Persistence.createEntityManagerFactory("manuPU");
           em = emf.createEntityManager();
           tx = em.getTransaction();
           tx.begin();
           ServiceFactory.createTaskServices().assignColaborator(tareaVo, usuarioVo,em);
           ServiceFactory.createUserServices().assignTask(tareaVo, usuarioVo, em);
           tx.commit();  
        }
         catch(Exception e) {
            if(em!=null && tx!=null) {
                tx.rollback();
                e.printStackTrace();
            }
        }
        finally {
            CloseEntityManager.close(em);
        }
    }

   
}
    

